﻿using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Infrastructure;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace aier.wx.api.selfhost
{

	public class BasicAuth
	{
		private const string WWWAuthenticateHeader = "WWW-Authenticate";
		public  BasicAuthenticationIdentity ParseAuthorizationHeader(HttpRequestMessage request)
		{
			string authHeader = null;
			var auth = request.Headers.Authorization;
			if (auth != null && auth.Scheme == "Basic")
				authHeader = auth.Parameter;

			if (string.IsNullOrEmpty(authHeader))
				return null;

			authHeader = Encoding.Default.GetString(Convert.FromBase64String(authHeader));

			// find first : as password allows for :
			int idx = authHeader.IndexOf(':');
			if (idx < 0)
				return null;

			string username = authHeader.Substring(0, idx);
			string password = authHeader.Substring(idx + 1);

			return new BasicAuthenticationIdentity(username, password);
		}


		/// <summary>
		/// Send the Authentication Challenge request
		/// </summary>
		/// <param name="message"></param>
		/// <param name="actionContext"></param>
		void Challenge(HttpRequestMessage request, HttpResponseMessage response)
		{
			//var host = request.RequestUri.DnsSafeHost;
			var host = "no auth";
			response.StatusCode = HttpStatusCode.Unauthorized;
			//response.Headers.Remove(WWWAuthenticateHeader);
			//response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Basic"));
			response.Headers.Add(WWWAuthenticateHeader, string.Format("Basic realm=\"{0}\"", host));


		}


		public bool IsSwagger(IOwinRequest request)
		{
			return request.Uri.PathAndQuery.Contains("/swagger");
		}
	}



	//public class BasicAuthenticationOptions : AuthenticationOptions
	//{
	//	public BasicAuthenticationMiddleware.CredentialValidationFunction CredentialValidationFunction { get; private set; }
	//	public string Realm { get; private set; }

	//	public BasicAuthenticationOptions(string realm, BasicAuthenticationMiddleware.CredentialValidationFunction validationFunction)
	//		: base("Basic")
	//	{
	//		Realm = realm;
	//		CredentialValidationFunction = validationFunction;
	//	}
	//}

	//public class BasicAuthenticationMiddleware : AuthenticationMiddleware<BasicAuthenticationOptions>
	//{
	//	public delegate Task<IEnumerable<Claim>> CredentialValidationFunction(string id, string secret);

	//	public BasicAuthenticationMiddleware(OwinMiddleware next, BasicAuthenticationOptions options)
	//		: base(next, options)
	//	{ }

	//	protected override AuthenticationHandler<BasicAuthenticationOptions> CreateHandler()
	//	{
	//		return new BasicAuthenticationHandler(Options);
	//	}
	//}

	//class BasicAuthenticationHandler : AuthenticationHandler<BasicAuthenticationOptions>
	//{
	//	private readonly string _challenge;

	//	public BasicAuthenticationHandler(BasicAuthenticationOptions options)
	//	{
	//		_challenge = "Basic realm=" + options.Realm;
	//	}

	//	protected override async Task<AuthenticationTicket> AuthenticateCoreAsync()
	//	{
	//		var authzValue = Request.Headers.Get("Authorization");
	//		if (string.IsNullOrEmpty(authzValue) || !authzValue.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase))
	//		{
	//			return null;
	//		}

	//		var token = authzValue.Substring("Basic ".Length).Trim();
	//		var claims = await TryGetPrincipalFromBasicCredentials(token, Options.CredentialValidationFunction);

	//		if (claims == null)
	//		{
	//			return null;
	//		}
	//		else
	//		{
	//			var id = new ClaimsIdentity(claims, Options.AuthenticationType);
	//			return new AuthenticationTicket(id, new AuthenticationProperties());
	//		}
	//	}

	//	protected override Task ApplyResponseChallengeAsync()
	//	{
	//		if (Response.StatusCode == 401)
	//		{
	//			var challenge = Helper.LookupChallenge(Options.AuthenticationType, Options.AuthenticationMode);
	//			if (challenge != null)
	//			{
	//				Response.Headers.AppendValues("WWW-Authenticate", _challenge);
	//			}
	//		}

	//		return Task.FromResult<object>(null);
	//	}

	//	async Task<IEnumerable<Claim>> TryGetPrincipalFromBasicCredentials(string credentials,
	//		BasicAuthenticationMiddleware.CredentialValidationFunction validate)
	//	{
	//		string pair;
	//		try
	//		{
	//			pair = Encoding.UTF8.GetString(
	//				Convert.FromBase64String(credentials));
	//		}
	//		catch (FormatException)
	//		{
	//			return null;
	//		}
	//		catch (ArgumentException)
	//		{
	//			return null;
	//		}

	//		var ix = pair.IndexOf(':');
	//		if (ix == -1)
	//		{
	//			return null;
	//		}

	//		var username = pair.Substring(0, ix);
	//		var pw = pair.Substring(ix + 1);

	//		return await validate(username, pw);
	//	}
	//}

	//public static class BasicAuthnMiddlewareExtensions
	//{
	//	public static IAppBuilder UseBasicAuthentication(this IAppBuilder app, string realm, BasicAuthenticationMiddleware.CredentialValidationFunction validationFunction)
	//	{
	//		var options = new BasicAuthenticationOptions(realm, validationFunction);
	//		return app.UseBasicAuthentication(options);
	//	}

	//	public static IAppBuilder UseBasicAuthentication(this IAppBuilder app, BasicAuthenticationOptions options)
	//	{
	//		return app.Use<BasicAuthenticationMiddleware>(options);
	//	}
	//}

}
